<?php

class csMenu {
	
	public $menu_name;
	public $menu_div_html_options;
	public $active_element_id;
	public $default_element_id;
	public $recursion_limit = 10;
	public $element_tpl;
	public $sort = null;
	protected $recursion_loop_security = array(
	);
	protected $element_tbl;

	public function __construct($params = null) {
		
		$this -> element_tbl = array(
		);
		
		if (isset($params['recursion_limit']))
			$this -> recursion_limt = $params['recursion_limit'];
		if (isset($params['default_element_id'])) {
			$this -> default_element_id = $params['default_element_id'];
			$this -> active_element_id = $this -> default_element_id;
		}
		if (isset($params['element_tpl']))
			$this -> element_tpl = $params['element_tpl'];
		if (isset($params['menu_name']))
			$this -> menu_name = $params['menu_name'];
		if (isset($params['menu_div_html_options']))
			$this -> menu_div_html_options = $params['menu_div_html_options'];
		if (isset($params['sort']))
			$this -> sort = $params['sort'];
	}

	public function add_element($element_obj, $force_regularize = false) {
		if (! ($element_obj instanceof csMenuElement)) {
			throw new csException(translate('Invalid menu element'), 888068);
		} else {
			$eid = $element_obj -> get_id();
			$this -> element_tbl[$eid] = $element_obj;
		}
		
		if ($force_regularize) {
			$this -> regularize();
		}
	}

	public function regularize() {
		$this -> sort_elements();
		$this -> find_all_childrens();
	}

	protected function sort_elements() {
		uasort($this -> element_tbl, 'cmp_obj_sort');
		$this -> element_tbl = array_reverse($this -> element_tbl, true);
	}

	protected function find_all_childrens() {
		foreach ($this -> element_tbl as $eid => $elem) {
			if ($elem -> parent && isset($this -> element_tbl[$elem -> parent])) {
				$id = $elem -> get_id();
				$this -> element_tbl[$elem -> parent] -> add_child($id);
			}
		}
	}

	public function set_element_active($element_id) {
		if (isset($this -> element_tbl[$element_id])) {
			$this -> element_tbl[$element_id] -> active = true;
			try {
				$this -> set_element_unroll($element_id);
			} catch (csException $e) {
				throw new csException($e -> getMessage(), $e -> getCode());
			}
		}
	}

	public function set_element_unroll($element_id, $level = 0) {
		if (isset($this -> element_tbl[$element_id])) {
			$this -> element_tbl[$element_id] -> unroll = true;
		}
		if ($level > $this -> recursion_limit)
			throw new csException(translate('Recursion overflow'), 888001);
		
		$this -> recursion_loop_security[] = $element_id;
		
		if ($this -> element_tbl[$element_id] -> parent) {
			if (in_array($this -> element_tbl[$element_id] -> parent, $this -> recursion_loop_security)) {
				throw new csException(translate('Recursion loop'), 888002);
			}
			return $this -> set_element_unroll($this -> element_tbl[$element_id] -> parent, $level + 1);
		}
		$this -> recursion_loop_security = array(
		);
	}

	public function get_parents($element_id, $level = 0, $parent_tbl = array()) {
		if (isset($this -> element_tbl[$element_id])) {
			$parent_tbl[] = $element_id;
		}
		
		if (isset($this -> element_tbl[$element_id]) && $this -> element_tbl[$element_id] -> parent) {
			$this -> get_parents($this -> element_tbl[$element_id] -> parent, $level ++, $parent_tbl);
		} else {
			return $parent_tbl;
		}
	}

	public function get_navigation_path($element_id = null) {
		if ($element_id === null) {
			$element_id = $this -> active_element_id;
		}
		if ($element_id === null) {
			return array(
			);
		}
		$parents = $this -> get_parents($element_id);
		$parents = array_reverse($parents);
		$navigation_path = array(
		);
		
		foreach ($parents as $parent) {
			if (! isset($this -> element_tbl[$parent])) {
				continue;
			}
			$navigation_path[] = array(
				'id' => $parent, 
				'name' => $this -> element_tbl[$parent] -> name, 
				'url' => $this -> element_tbl[$parent] -> url, 
				'active' => ($parent == $element_id ? true : false)
			);
		}
		return $navigation_path;
	}

	public function add_elements($element_tbl) {
		foreach ($element_tbl as $ide => $element_obj) {
			$this -> add_element($element_obj);
		}
		$this -> regularize();
	}

	public function display() {
		$this -> recursion_loop_security = array(
		);
		foreach ($this -> element_tbl as $eid => $element) {
			if ($element -> parent === null) {
				$this -> display_element($eid);
			}
		}
	}

	protected function display_element($element_id, $level = 0) {
		if ($level > $this -> recursion_limit) {
			throw new csException(translate('Recursion overflow'), 888003);
		}
		if (in_array($element_id, $this -> recursion_loop_security)) {
			throw new csException(translate('Recursion loop'), 888004);
		}
		
		$this -> recursion_loop_security[] = $element_id;
		
		$GLOBALS['tpl_system'] -> tpl_vars['menu_el'] = array(
			'name' => $this -> element_tbl[$element_id] -> name, 
			'url' => $this -> element_tbl[$element_id] -> url, 
			'active' => $this -> element_tbl[$element_id] -> active, 
			'html_options' => $this -> element_tbl[$element_id] -> html_options
		);
		$GLOBALS['tpl_system'] -> tpl_vars['menu_level'] = $level;
		
		$GLOBALS['tpl_system'] -> display($this -> element_tpl);
		
		if ($this -> element_tbl[$element_id] -> unroll && $this -> element_tbl[$element_id] -> are_childrens()) {
			$child_tbl = $this -> element_tbl[$element_id] -> get_childrens();
			foreach ($child_tbl as $cid => $eid) {
				$this -> display_element($eid, $level + 1);
			}
		}
		$this -> recursion_loop_security = array(
		);
	}

	public function get_element($id) {
		return (isset($this -> element_tbl[$id]) ? $this -> element_tbl[$id] : null);
	}
}

class csMenuElement {
	protected $id;
	protected $child_tbl = array(
	);
	
	public $parent = null;
	public $active = false;
	public $unroll = false;
	public $sort = 100;
	public $name;
	public $url;
	public $html_options;

	public function __construct($params = null) {
		if (! isset($params['id']) || $params['id'] === null) {
			throw new csException(translate('Invalid menu element'), 888067);
		} else {
			$this -> id = $params['id'];
		}
		if (isset($params['parent']))
			$this -> parent = $params['parent'];
		if (isset($params['name']))
			$this -> name = $params['name'];
		if (isset($params['url']))
			$this -> url = $params['url'];
		if (isset($params['active']))
			$this -> active = $params['active'];
		if (isset($params['unroll']))
			$this -> unroll = $params['unroll'];
		if (isset($params['sort']))
			$this -> sort = $params['sort'];
		if (isset($params['html_options']))
			$this -> html_options = $params['html_options'];
	}

	public function get_id() {
		return $this -> id;
	}

	public function get_childrens() {
		return $this -> child_tbl;
	}

	public function are_childrens() {
		if ($this -> child_tbl) {
			return true;
		} else {
			return false;
		}
	}

	public function add_child($child) {
		if (! in_array($child, $this -> child_tbl)) {
			$this -> child_tbl[] = $child;
		}
	}

	public function remove_child($child) {
		$key = array_search($child, $this -> child_tbl);
		
		if ($key !== null) {
			unset($this -> child_tbl[$key]);
		}
	}

	public function remove_all_childrens() {
		$this -> child_tbl = array(
		);
	}
}

class csMenuElementDirect extends csMenuElement {

	public function __construct($row = null, $cs_params = null, $pass_params = null) {
		parent::__construct(array(
			'id' => (isset($row['id_me']) ? $row['id_me'] : null), 
			'parent' => (isset($row['parent_me']) ? $row['parent_me'] : null), 
			'name' => (isset($row['name_me']) ? $row['name_me'] : null), 
			'url' => (isset($row['href_me']) ? $row['href_me'] : null), 
			'unroll' => (isset($row['unroll_me']) ? $row['unroll_me'] : null), 
			'sort' => (isset($row['sort_me']) ? $row['sort_me'] : null)
		));
	}
}

class csMenuElementPlayers extends csMenuElementDirect {

	public function __construct($row = null, $cs_params = null, $pass_params = null) {
		if (isset($row['param1_me'])) {
			$row['href_me'] = $_SERVER["SCRIPT_NAME"] . url_params($cs_params, $pass_params, array(
				'action' => 'players', 
				'teamid' => $row['param1_me']
			));
		}
		parent::__construct($row, $cs_params, $pass_params);
	}
}

class csMenuElementMainpage extends csMenuElementDirect {

	public function __construct($row = null, $cs_params = null, $pass_params = null) {
		$row['href_me'] = $_SERVER["SCRIPT_NAME"] . url_params($cs_params, array(
			'debug'
		));
		
		parent::__construct($row, $cs_params, $pass_params);
	}
}
?>
